package com.example.matchandroiddevices.test.util;

import com.example.matchandroiddevices.test.readers.InventoryScanResult;

import java.util.ArrayList;
import java.util.Arrays;

public class RR7036ReaderUtil {
    // CRC计算方法
    public static byte[] calculateCrc(byte[] data, int length) {
        int currentCrcValue = 0xffff; // PRESET_VALUE
        int polynomial = 0x8408;      // POLYNOMIAL

        for (int i = 0; i < length; i++) {
            currentCrcValue ^= (data[i] & 0xFF);
            for (int j = 0; j < 8; j++) {
                if ((currentCrcValue & 0x0001) != 0) {
                    currentCrcValue = (currentCrcValue >> 1) ^ polynomial;
                } else {
                    currentCrcValue = (currentCrcValue >> 1);
                }
            }
        }

        byte[] crc = new byte[2];
        crc[0] = (byte)(currentCrcValue & 0x00FF);         // LSB
        crc[1] = (byte)((currentCrcValue >> 8) & 0x00FF);  // MSB
        return crc;
    }
    /**
     * 创建打开感应场(Open RF)命令
     * @param readerAddress 读写器地址
     * @return 格式化的命令字节数组
     */
    public static byte[] createOpenRFCommand(byte readerAddress) {
        // 根据文档：
        // Len = 0x05 (总长度5字节，不含自身)
        // Com_adr = readerAddress (读写器地址)
        // Cmd = 0x00 (读写器自定义命令)
        // State = 0x02 (打开感应场)
        // Data[] = 无数据

        // 创建命令数据（不含CRC）
        byte[] commandData = new byte[4];
        commandData[0] = 0x05;             // Len: 5字节(不含自身)
        commandData[1] = readerAddress;    // Com_adr: 读写器地址
        commandData[2] = 0x00;             // Cmd: 读写器自定义命令
        commandData[3] = 0x02;             // State: 打开感应场

        // 计算CRC
        byte[] crc = calculateCrc(commandData, commandData.length);

        // 创建完整命令（含CRC）
        byte[] fullCommand = new byte[6];
        System.arraycopy(commandData, 0, fullCommand, 0, commandData.length);
        fullCommand[4] = crc[0];  // LSB of CRC
        fullCommand[5] = crc[1];  // MSB of CRC

        return fullCommand;
    }
    /**
     * 创建设置读写器为ISO15693模式的命令
     * @param readerAddress 读写器地址
     * @return 格式化的命令字节数组
     */
    public static byte[] createChangeToISO15693Command(byte readerAddress) {
        // 根据文档：
        // Len = 0x05 (总长度5字节，不含自身)
        // Com_adr = readerAddress (读写器地址)
        // Cmd = 0x00 (读写器自定义命令)
        // State = 0x06 (设置为ISO15693模式)
        // Data[] = 无数据

        // 创建命令数据（不含CRC）
        byte[] commandData = new byte[4];
        commandData[0] = 0x05;             // Len: 5字节(不含自身)
        commandData[1] = readerAddress;    // Com_adr: 读写器地址
        commandData[2] = 0x00;             // Cmd: 读写器自定义命令
        commandData[3] = 0x06;             // State: 设置为ISO15693模式

        // 计算CRC
        byte[] crc = calculateCrc(commandData, commandData.length);

        // 创建完整命令（含CRC）
        byte[] fullCommand = new byte[6];
        System.arraycopy(commandData, 0, fullCommand, 0, commandData.length);
        fullCommand[4] = crc[0];  // LSB of CRC
        fullCommand[5] = crc[1];  // MSB of CRC

        return fullCommand;
    }
    /**
     * 创建ISO15693协议的Inventory-scan命令
     * @param readerAddress 读写器地址
     * @param useAFI 是否使用AFI
     *        true: 使用AFI进行部分询查(State=0x06)
     *        false: 进行全体询查(State=0x02)
     * @return 格式化的命令字节数组
     */
    public static byte[] createInventoryScanCommand(byte readerAddress, boolean useAFI) {
        // 根据文档：
        // Len = 0x05 (总长度5字节，不含自身)
        // Com_adr = readerAddress (读写器地址)
        // Cmd = 0x01 (ISO15693协议命令)
        // State = 0x06(部分询查) 或 0x02(全体询查)
        // Data[] = 无数据

        // 创建命令数据（不含CRC）
        byte[] commandData = new byte[4];
        commandData[0] = 0x05;             // Len: 5字节(不含自身)
        commandData[1] = readerAddress;    // Com_adr: 读写器地址
        commandData[2] = 0x01;             // Cmd: ISO15693协议命令
        commandData[3] = useAFI ? (byte)0x06 : (byte)0x02;  // State: 根据是否使用AFI选择

        // 计算CRC
        byte[] crc = calculateCrc(commandData, commandData.length);

        // 创建完整命令（含CRC）
        byte[] fullCommand = new byte[6];
        System.arraycopy(commandData, 0, fullCommand, 0, commandData.length);
        fullCommand[4] = crc[0];  // LSB of CRC
        fullCommand[5] = crc[1];  // MSB of CRC

        return fullCommand;
    }
    /**
     * 解析Inventory-scan命令的响应
     * @param response 读卡器返回的原始响应数据
     * @return Inventory-scan结果对象
     */
    public static InventoryScanResult parseInventoryScanResponse(byte[] response) {
        InventoryScanResult result = new InventoryScanResult();

        // 检查基本格式
        if (response.length < 4) { // 至少需要Len+Com_adr+Status
            result.isSuccess = false;
            result.errorMessage = "响应数据过短";
            return result;
        }

        // 基本信息
        result.responseLength = response[0] & 0xFF;
        result.readerAddress = response[1] & 0xFF;
        result.status = response[2] & 0xFF;

        // 检查状态码
        if (result.status != 0x00) {
            result.isSuccess = false;
            result.errorMessage = "命令执行失败，状态码: 0x" + String.format("%02X", result.status);
            return result;
        }

        // 检查是否有标签数据
        if (response.length <= 5) { // Len+Com_adr+Status+CRC(2)
            result.isSuccess = true;
            result.message = "命令执行成功，但未找到标签";
            return result;
        }

        // 检查响应长度有效性
        // 文档说明响应长度为 0x04+n*9，其中n为扫描到的标签数量，n最大值为16
        int tagCount = (result.responseLength - 4) / 9; // 计算标签数量

        if (tagCount > 0) {
            result.isSuccess = true;
            result.message = String.format("命令执行成功，找到 %d 个标签", tagCount);

            // 解析每个标签的UID
            result.tagUids = new ArrayList<>();

            for (int i = 0; i < tagCount; i++) {
                // 每个标签的DSFID和UID占9个字节：DSFID(1字节) + UID(8字节)
                byte[] uidData = new byte[9];
                System.arraycopy(response, 3 + i * 9, uidData, 0, 9);

                InventoryScanResult.TagData tag = new InventoryScanResult.TagData();
                tag.dsfid = uidData[0];

                // 提取8字节UID
                byte[] uid = new byte[8];
                System.arraycopy(uidData, 1, uid, 0, 8);
                tag.uid = uid;
                result.tagUids.add(tag);
            }
        }

        return result;
    }
    // 创建获取读写器信息的命令
    public static byte[] createGetReaderInfoCommand(byte readerAddress) {
        // 创建命令数据（不含CRC）
        byte[] commandData = new byte[4];
        commandData[0] = 0x05;             // Len: 5字节(不含自身)
        commandData[1] = readerAddress;    // Com_adr: 读写器地址
        commandData[2] = 0x00;             // Cmd: 读写器自定义命令
        commandData[3] = 0x00;             // State: 获取读写器信息

        // 计算CRC
        byte[] crc = calculateCrc(commandData, commandData.length);

        // 创建完整命令（含CRC）
        byte[] fullCommand = new byte[6];
        System.arraycopy(commandData, 0, fullCommand, 0, commandData.length);
        fullCommand[4] = crc[0];  // LSB of CRC
        fullCommand[5] = crc[1];  // MSB of CRC

        return fullCommand;
    }
    public static String parseReaderInfoSimple(byte[] response) {
        StringBuilder info = new StringBuilder();

        try {
            // 基本信息
            info.append("数据长度: ").append(response[0] & 0xFF).append("\n");
            info.append("读卡器地址: 0x").append(String.format("%02X", response[1] & 0xFF)).append("\n");
            info.append("状态: 0x").append(String.format("%02X", response[2] & 0xFF)).append("\n");

            // 只有当响应足够长时才解析详细数据
            if (response.length >= 11) {
                // 版本号 (2字节)
                int version = (response[4] & 0xFF) | ((response[3] & 0xFF) << 8);
                info.append("版本号: 0x").append(String.format("%04X", version)).append("\n");

                // RFU (2字节，保留)
                int rfu = (response[6] & 0xFF) | ((response[5] & 0xFF) << 8);
                info.append("RFU: 0x").append(String.format("%04X", rfu)).append("\n");

                // 读写器类型和传输类型 (2字节)
                int readerType = (response[8] & 0xFF) | ((response[7] & 0xFF) << 8);
                info.append("读写器类型: 0x").append(String.format("%04X", readerType)).append("\n");

                // 判断是否为RR7036
                if ((readerType & 0xFF) == 0x66) {
                    info.append("设备类型: RR7036\n");
                } else {
                    info.append("设备类型: 未知(0x").append(String.format("%02X", readerType & 0xFF)).append(")\n");
                }

                // 支持的协议
                info.append("支持的协议: ");
                if ((readerType & (1 << 11)) != 0) info.append("ISO/IEC 15693 ");
                if ((readerType & (1 << 10)) != 0) info.append("ISO/IEC 14443 ");
                if ((readerType & (1 << 9)) != 0) info.append("ICODE UID ");
                info.append("\n");

                // InventoryScanTime (2字节)
                int inventoryScanTime = (response[10] & 0xFF) | ((response[9] & 0xFF) << 8);
                info.append("库存扫描时间: ").append(inventoryScanTime).append("ms\n");
            }

            // 十六进制形式展示整个响应
            info.append("原始响应数据: ");
            for (byte b : response) {
                info.append(String.format("%02X ", b & 0xFF));
            }

        } catch (Exception e) {
            info.append("解析异常: ").append(e.getMessage()).append("\n");
            info.append("原始数据: ").append(Arrays.toString(response));
        }

        return info.toString();
    }
}
